import { date2Int } from './datetime'
import { guid } from './uuid'
import { toastError } from './toast'
import { uniqueObjAryProp } from './array'

/** 检查文件是否是图像文件以及是否超出指定大小
 * @param {Object} file 要检测的文件
 * @param {Number} sizeLimit 指定尺寸大小（单位是k）
 * @returns {Boolean} 文件是否合法
 */
export function checkImageFileTypeSize(file, sizeLimit) {
  // 格式校验
  const isPNG = file.type === 'image/png'
  const isJPEG = file.type === 'image/jpeg'
  const isJPG = file.type === 'image/jpg'
  const isGIF = file.type === 'image/gif'
  if (!isPNG && !isJPEG && !isJPG && !isGIF) {
    this.$message({
      message: '上传的图片只能是 jpg、png、jpeg、gif 格式!',
      type: 'error',
      center: true,
    })
    return false
  }
  // 尺寸大小校验
  const isLt2M = file.size / 1024 < sizeLimit
  if (!isLt2M) {
    this.$message({
      message: '上传的图片大小不能超过 2MB!',
      type: 'error',
      center: true,
    })
    return false
  }
  return true
}

/** 检查文件是否是图像文件
 * @param {Object} file 要检测的文件
 * @returns {Boolean} 是否是图像文件
 */
export function checkImageFile(file) {
  // firefox image/jpeg、 image/bmp、image/gif、image/png
  // ie6     image/pjpeg、image/bmp、image/gif、image/x-png
  // ie7     image/pjpeg、image/bmp、image/gif、image/x-png
  // ie8     image/pjpeg、image/bmp、image/gif、image/x-png
  // 格式校验
  const isBMP = file.type === 'image/bmp'
  const isPNG = file.type === 'image/png' || file.type === 'image/x-png'
  const isJPEG = file.type === 'image/jpeg' || file.type === 'image/pjpeg'
  const isJPG = file.type === 'image/jpg'
  const isGIF = file.type === 'image/gif'
  return !(!isBMP && !isPNG && !isJPEG && !isJPG && !isGIF)
}

/** 检查要上传的单个文件的扩展名是否在指定的文件格式扩展名里
 * @param {Object} file 要上传的单个文件
 * @param {String} allowedExtString 允许上传的文件扩展名字符串，例如".doc.docx.wps'
 * @param {Boolean} 返回值
 */
export function isAllowedFile(file, allowedExtString) {
  // indexOf()===-1说明没有找到
  return allowedExtString.indexOf(getExtByName(file)) !== -1
}

/** 格式化文件大小，size为字节大小，保留两位小数
 * @param {Number} size 初始文件大小
 * @returns {String} 格式化后的字符串
 */
export function formatFileSize(size) {
  if (!size) {
    return ''
  }
  // byte
  var num = 1024.0
  // Math.pow(x,y) 返回 x 的 y 次幂的值
  // NumberObject.toFixed(num) 把 num 四舍五入为指定小数位数的数字
  if (size < num) {
    return size + 'B'
  }
  if (size < Math.pow(num, 2)) {
    return (size / num).toFixed(2) + 'K'
  }
  if (size < Math.pow(num, 3)) {
    return (size / Math.pow(num, 2)).toFixed(2) + 'M'
  }
  if (size < Math.pow(num, 4)) {
    return (size / Math.pow(num, 3)).toFixed(2) + 'G'
  }
  return (size / Math.pow(num, 5)).toFixed(2) + 'T'
}

/** 根据文件扩展名检查此种文件的上传大小限制
 * @param {Object} file 要检测的文件
 * @param {Object} uploadConfig 文件上传的系统设置
 * @returns {Boolean} 是否在指定大小范围内
 */
export function isAllowedSizeByExt(file, uploadConfig) {
  const fileSize = file.size / 1024
  switch (getExtByName(file)) {
    case '.gif':
    case '.jpg':
    case '.jpeg':
    case '.bmp':
    case '.png':
    case '.tiff':
    case '.wmf':
    case '.ico':
      return fileSize <= uploadConfig.allowedSizeImg
    case '.txt':
    case '.doc':
    case '.docx':
    case '.xls':
    case '.xlsx':
    case '.chm':
    case '.pdf':
      return fileSize <= uploadConfig.allowedSizeDoc
    case '.zip':
    case '.rar':
    case '.7z':
      return fileSize <= uploadConfig.allowedSizeZip
    case '.avi':
    case '.flv':
    case '.mp3':
    case '.mp4':
    case '.mpeg':
    case '.wma':
    case '.wav':
    case '.swf':
      return fileSize <= uploadConfig.allowedSizeMedia
    default:
      return false
  }
}

/** 检查文件大小
 * @param {Object} file 要检测的文件
 * @param {Number} sizeLimit 大小限制数（单位是M）
 * @returns {Boolean} 是否在指定大小范围内
 */
export function isAllowedSize(file, sizeLimit) {
  return file.size / 1024 / 1024 < sizeLimit
}

/** 根据文件扩展名得到此种文件的上传大小限制
 * @param {Object} file 要检测的文件
 * @param {Object} uploadConfig 文件上传的系统设置
 * @returns {Number} 此种文件的上传大小限制
 */
export function getSizeLimitByExt(file, uploadConfig) {
  switch (getExtByName(file)) {
    case '.gif':
    case '.jpg':
    case '.jpeg':
    case '.bmp':
    case '.png':
    case '.tiff':
    case '.wmf':
    case '.ico':
      return uploadConfig.allowedSizeImg
    case '.txt':
    case '.doc':
    case '.docx':
    case '.xls':
    case '.xlsx':
    case '.chm':
    case '.pdf':
      return uploadConfig.allowedSizeDoc
    case '.zip':
    case '.rar':
    case '.7z':
      return uploadConfig.allowedSizeZip
    case '.avi':
    case '.flv':
    case '.mp3':
    case '.mp4':
    case '.mpeg':
    case '.wma':
    case '.wav':
    case '.swf':
      return uploadConfig.allowedSizeMedia
    default:
      return 0
  }
}

/** 过滤要上传的多个文件数组，只保留允许上传的文件
 * @param {Array} files 要上传的多个文件数组
 * @param {String} allowedExtString 允许上传的文件扩展名字符串，例如".doc.docx.wps'
 * @param {Array} 返回允许上传的文件数组
 */
export function filterFilesByExt(files, allowedExtString) {
  if (!files || files.length === 0) return []
  let message = ''
  const returnFileList = []
  for (let i = 0; i < files.length; i++) {
    if (isAllowedFile(files[i], allowedExtString)) {
      returnFileList.push(files[i])
    } else {
      message = message + '[ ' + files[i].name + ' ]、'
    }
  }
  if (message.endsWith('、')) {
    toastError(message.substring(0, message.length - 1) + '的格式不正确')
  }
  return returnFileList
}

/** 检查要上传的多个文件数组里每个文件的大小是否小于指定的大小
 * @param {Array} files 要上传的多个文件数组
 * @param {Number} config 上传的设置
 * @param {Array} 返回允许上传的文件数组
 */
export function filterFilesBySize(files, config) {
  if (!files || files.length === 0) return []
  if (!config) return []
  let message = ''
  const returnFileList = []
  for (let i = 0; i < files.length; i++) {
    if (isAllowedSizeByExt(files[i], config)) {
      returnFileList.push(files[i])
    } else {
      message += '[' + files[i].name + ']的文件大小不能超过 '
      message += getSizeLimitByExt(files[i], config) / 1024 + ' M、'
    }
  }
  if (message.endsWith('、')) {
    toastError(message.substring(0, message.length - 1))
  }
  return returnFileList
}

/** 过滤要上传的多个文件数组里重名的文件
 * @param {Array} files 要上传的多个文件数组
 * @param {Array} 返回允许上传的文件数组
 */
export function filterFilesByName(files) {
  if (!files || files.length <= 1) return files
  return uniqueObjAryProp(files, 'name')
  // const aryClean = []
  // let flagHasFile = false
  // files.forEach((file) => {
  //   for (let i = 0; i < aryClean.length; i++) {
  //     if (aryClean[i].name === file.name && aryClean[i].size === file.size) {
  //       flagHasFile = true
  //       break
  //     }
  //   }
  //   if (!flagHasFile) {
  //     aryClean.push(file)
  //   }
  // })
  // return aryClean
}

/** 获取文件扩展名，包含“.”
 * @param {Object} file 要检测的文件
 * @returns {String} 文件扩展名
 */
export function getExtByName(file) {
  var fileName = file.name
  // 第1种方法
  // return '.' + (fileName).match(/\.([0-9a-z]+)(?:[\?#]|$)/i)
  // 第2种方法
  // split将字符串以指定符号分割成数组，pop得到数组最后一个元素
  // return '.' + fileName.split('.').pop()
  // 第3种方法
  // 取到文件名开始到最后一个点的长度
  const lastDotPosition = fileName.lastIndexOf('.')
  // 取到文件名长度
  const fileNameLength = fileName.length
  // 返回文件的扩展名，注意是带了.
  return fileName.substring(lastDotPosition, fileNameLength)
}

/** 根据文件类型得到扩展名，包含“.”
 * @param {Object} file 要检测的文件
 * @returns {String} 文件扩展名
 */
export function getExtByType(file) {
  if (file.type === 'image/png') return '.png'
  if (file.type === 'image/jpeg') return '.jpeg'
  if (file.type === 'image/jpg') return '.jpg'
  if (file.type === 'image/gif') return '.gif'
  return ''
}

/** 设置上传到七牛云的文件名
 * @param {Object} file 要上传到七牛云的文件
 * @param {String} prefix 文件名前缀
 * @returns {String} 上传到七牛云的文件名
 */
export function setQiNiuKey(file, prefix) {
  if (!prefix) {
    prefix = 'a'
  }
  // 得到文件扩展名
  const extName = getExtByName(file)
  // 设置上传到七牛云后的文件名
  const dateString = date2Int(new Date())
  // g=global, m=multiLine
  const reg = new RegExp('-', 'gm')
  var guidString = guid().replace(reg, '')
  const cloudFileName = prefix + dateString + guidString.substring(0, 17)
  return cloudFileName + extName
}

/**
 * 解析blob响应内容并下载
 * @param {*} resp blob响应内容
 */
export function resolveBlob(resp) {
  // const mimeType = this.$store.getters.MimeType
  var blob = new Blob([resp.data], {
    type: resp.data.type,
  })
  if (resp.headers['content-disposition']) {
    // 从 response 的 headers 中获取 filename
    // 后端已经在 response.setHeader("Content-disposition", attachment; filename=xxxx.docx") 中设置好文件名了
    var patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*')
    var disposition = decodeURI(resp.headers['content-disposition'])
    var fileName = patt.exec(disposition)[1]
    fileName = fileName.replace(/\\"/g, '')
  } else {
    fileName = 'fileName'
  }
  const objectUrl = URL.createObjectURL(blob)
  // 浏览器兼容，Google和火狐支持a标签的download，IE不支持
  if (window.navigator && window.navigator.msSaveBlob) {
    // IE浏览器、微软浏览器 Edge 下载文件时必须要重命名文件才可以打开
    // IE可不重命名，以防万一，所以都写上比较好 */
    window.navigator.msSaveBlob(blob, fileName)
  } else {
    const aLink = document.createElement('a')
    aLink.href = objectUrl
    // 设置下载文件名称
    aLink.setAttribute('download', fileName)
    document.body.appendChild(aLink)
    aLink.click()
    document.body.removeChild(aLink)
  }
  // 释放这个临时的对象URL
  URL.revokeObjectURL(objectUrl)
}

/**
 * 将服务器返回的Byte[]转换成Base64图片
 * @param {Array} buffer 服务器返回的Byte[]
 */
export function aryBuffer2Base64(buffer) {
  var binary = ''
  var bytes = new Uint8Array(buffer)
  var len = bytes.byteLength
  for (var i = 0; i < len; i++) {
    binary += String.fromCharCode(bytes[i])
  }
  return 'data:image/jpeg;base64,' + window.btoa(binary)
}

/**
 * 从服务器读到上传文件的配置信息数组，将数组值转到上传配置对象中
 * @param {Array} configAry 服务器返回的上传文件的配置信息数组
 * @returns {Object} 上传配置对象
 */
export function setUploadConfig(configAry) {
  if (!(configAry && configAry.length > 5)) {
    return null
  }
  const uploadConfig = {}
  for (let i = 0; i < configAry.length; i++) {
    // 所有允许上传的文件扩展名
    if (configAry[i].name === 'AllowedExt') {
      uploadConfig.AllowedExt = configAry[i].value
    }
    // 所有允许上传的图像文件扩展名
    if (configAry[i].name === 'AllowedExtImg') {
      uploadConfig.AllowedExtImg = configAry[i].value
    }
    // 允许上传的图像文件大小，以K为单位
    if (configAry[i].name === 'AllowedSizeImg') {
      uploadConfig.AllowedSizeImg = configAry[i].value
    }
    // 允许上传的文本文件大小，以K为单位
    if (configAry[i].name === 'AllowedSizeDoc') {
      uploadConfig.AllowedSizeDoc = configAry[i].value
    }
    // 允许上传的压缩文件大小，以K为单位
    if (configAry[i].name === 'AllowedSizeZip') {
      uploadConfig.AllowedSizeZip = configAry[i].value
    }
    // 允许上传的多媒体文件大小，以K为单位
    if (configAry[i].name === 'AllowedSizeMedia') {
      uploadConfig.AllowedSizeMedia = configAry[i].value
    }
  }
  return uploadConfig
}

/**
 * 验证要上传的文件数组，并过滤掉不符合扩展名、文件大小、去重等限制的文件
 * @param {Array} files 选中的要上传的文件数组
 * @param {String} allowedExtString 允许上传的文件扩展名字符串
 * @param {Object} uploadConfig 上传配置
 * @returns {Object} 符合条件的可以上传的文件数组
 */
export function validUploadFiles(files, allowedExtString, uploadConfig) {
  // 验证是否为空
  if (files.length === 0) {
    toastError('请选择要上传的文件!')
    return []
  }
  // 读取配置
  if (!uploadConfig) {
    toastError('读取上传配置出错！')
    return []
  }
  if (!allowedExtString || allowedExtString === '') {
    allowedExtString = uploadConfig.allowedExt
  }
  // 过滤扩展名不正确的文件，并给出提示
  let result = filterFilesByExt(files, allowedExtString)
  if (result.length === 0) {
    return []
  }
  // 过滤文件大小不正确的文件，并给出提示
  result = filterFilesBySize(result, uploadConfig)
  if (result.length === 0) {
    return []
  }
  // 去除重名文件
  return filterFilesByName(result)
}

/**
 * @param file_url 文件地址
 * @return promise
 */
export function readFile(file_url) {
  console.log('fileName:', file_url)
  // 方法一：创建一个新的xhr对象
  let xhr = null
  const okStatus = document.location.protocol === 'file' ? 0 : 200
  // eslint-disable-next-line
  xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
  xhr.open('GET', file_url, false)
  xhr.overrideMimeType('text/html;charset=utf-8')
  xhr.send(null)
  console.log('xhr:', xhr)
  return xhr.status === okStatus ? xhr.responseText : null
  // 方法二：利用 axios
  // this.$axios
  //   .get(fileName)
  //   .then((res) => {
  //     this.categoryList = res.data
  //   })
  //   .catch((err) => {
  //     console.log(err)
  //   })
  // 方法三
  // return new Promise(function(resolve, reject) {
  //   const xhr = new XMLHttpRequest()
  //   xhr.open('get', file_url, true)
  //   xhr.responseType = 'blob'
  //   xhr.onload = function() {
  //     if (this.status === 200) {
  //       const reader = new FileReader()
  //       reader.onload = function() {
  //         resolve(reader.result)
  //       }
  //       reader.readAsText(this.response)
  //     } else {
  //       console.log('err')
  //     }
  //   }
  //   xhr.send()
  // })
}

export function readFile1(urlFile) {
  // urlFile = '/static/data/spectators_index_20200802.txt'
  // const _this = this
  // const json = []
  let xhr = null
  if (window.XMLHttpRequest) {
    // code for all new browsers
    xhr = new XMLHttpRequest()
  } else if (window.ActiveXObject) {
    // code for IE5 and IE6
    xhr = new window.ActiveXObject('Microsoft.XMLHttp')
  }
  if (xhr != null) {
    xhr.open('get', urlFile, true)
    // 设置数据类型
    xhr.responseType = 'arraybuffer'
    xhr.onload = () => {
      if (xhr.status === 200) {
        console.log('xhr.response', xhr.response)
        debugger
        // 引入node  iconv-lite 插件 把GBK编码转utf8编码
        // const iconv = require('iconv-lite')
        // const data = new Uint8Array(xhr.response)
        //解析成字符串
        // const text = iconv.decode(data, 'gbk')
        const text = new Uint8Array(xhr.response)
        // console.log(text);
        if (text) {
          const arr = text.split('\n')
          if (arr != null && arr.length > 0) {
            let obj = {}
            for (let i = 0; i < arr.length; i++) {
              if (i > 0) {
                const val = arr[i].split(' ')
                if (val[0] === '01') {
                  obj.a1 = val[val.length - 1]
                }
              }
            }
          }
        }
      }
    }
    xhr.send()
  } else {
    alert('你的浏览器不支持XMLHttpRequest功能')
  }
}

/** 读取本地 TXT 文件，返回Promise，调用方式：
 * readTxtFile('/static/txt/1.txt').then(res => { console.log(res) })
 * @param urlTxtFile Txt文件地址
 * @return Promise
 */
export function readTxtFile(urlTxtFile) {
  return new Promise(function (resolve, reject) {
    let xhr = new XMLHttpRequest()
    xhr.open('get', urlTxtFile, true)
    xhr.responseType = 'blob'
    xhr.onload = function () {
      if (this.status == 200) {
        const reader = new FileReader()
        reader.onload = function () {
          resolve(reader.result)
        }
        reader.readAsText(this.response)
      } else {
        console.log('err')
        reject('TXT文件错误')
      }
    }
    xhr.send()
  })
}
